
import React, {Fragment} from "react";
import {Button, Form, Icon, message, Modal, Progress, Upload} from "antd";
import service from "../../libs/request";
import {diffProps} from "../../libs/funcs";
import CryptoJS from 'crypto-js';

class FormUpload extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            disabled: false,
            data:{},
            chunkSize:1024 * 1024 * 5, //切片的大小
            currentTrunk:0, //当前上传分片的索引
            percent:0,
            fileList: this.handleInitialValue(),
            is_show_process:false,
            previewVisible:false,
            previewImage: '',
        };

    }

    //获取文件名后缀
    getFileExtension(file) {
        const fileName = file.name;
        const lastDotIndex = fileName.lastIndexOf('.');

        if (lastDotIndex === -1) {
            return ''; // 没有后缀
        }

        return fileName.substr(lastDotIndex + 1);
    }
    generateHash = (data) => {
        // 使用某种哈希算法，例如 SHA-256
        // 这里只是一个示例，使用简单的 MD5 哈希
        const hash = CryptoJS.MD5(data).toString();
        return hash;
    };

    handleInitialValue = () => {
        try {
            if (Array.isArray(this.props.initialValue) && this.props.initialValue.length > 0 && this.props.initialValue[0].hasOwnProperty("url")){
                return this.props.initialValue;
            }

            return [];
        }catch (e) {
            return [];
        }
    };

    // 上传失败
    uploadError = () => {
        let data = {
            uid: (this.state.fileList.length + 1).toString,
            name: this.state.data["name"],
            status: 'error',
            url: "",
            thumbUrl: "",
        };
        this.setState({
            disabled: false,
            is_show_process:false,
            fileList: [...this.state.fileList,data]
        });
        message.error("上传失败")
    };

    // 上传成功
    uploadSuccess = (info) => {
        let data = {
            uid: info["unique_id"],
            name: info["fileName"],
            status: 'done',
            url: info["url"],
            thumbUrl: info["thump_url"],
        };
        let that = this;
        this.setState({
            disabled: false,
            is_show_process:false,
            fileList: this.props.single ? [data] : [...this.state.fileList,data],
            percent:100
        },function () {
            let obj = {};
            obj[that.props.field ? that.props.field : "default_upload_file"] = JSON.stringify(that.state.fileList);
            this.props.form.setFieldsValue(obj);
        });


    };

    sendFile = () => {
        console.log("当前分片",this.state.currentTrunk)
        let start = this.state.currentTrunk * this.state.chunkSize;

        let end = 0;
        if(this.state.currentTrunk+1 === this.state.data.chunkNum){
            end = this.state.data.len
        }else {
            end = start + this.state.chunkSize;
        }
        let blob = this.state.data.file.slice(start,end);
        let formData = new FormData();
        formData.append('file', blob);
        formData.append('fileName', this.state.data.name);
        formData.append('size', this.state.data.len);
        formData.append('type', this.state.data.type);
        formData.append('chunkNum', this.state.data.chunkNum);
        formData.append('chunk', (this.state.currentTrunk+1));
        formData.append('chunkSize', this.state.chunkSize);
        let config = {
            headers: {
                'Content-Type': 'multipart/form-data',
            }
        };
        service.post("/admin/react/upload/file",formData,config).then( response =>{
            if (response.data.code === 200 || response.data.code === 2222 || response.data.code === 1111){
                //处理存在分片的情况
                if (response.data.code === 1111){
                    console.log("已经存在分片");
                    console.log(response.data);
                    this.setState({
                        currentTrunk:response.data.index-1,
                        percent:((response.data.index-1) * 100) / this.state.data.chunkNum
                    },function () {
                        this.sendFile();
                    });
                }else { //正常情况
                    if (this.state.currentTrunk+1 === this.state.data.chunkNum){
                        this.uploadSuccess(response.data);
                        console.log("上传完成:",response.data)
                    }else {
                        this.setState({
                            currentTrunk:this.state.currentTrunk+1,
                            percent:((this.state.currentTrunk+1) * 100) / this.state.data.chunkNum
                        },function () {
                            this.sendFile();
                        });
                    }
                }
            }else {
                this.uploadError();
            }
        }).catch(error => {
            this.uploadError();
        })
    };

    // 检查文件类型
    checkFileType = (type) => {
        let fileType = this.props.fileType;
        if (!fileType){
            fileType = ["*"];
        }

        if (fileType.includes("*")){
             return true;
        }
        if (this.props.fileType){
            return !!this.props.fileType.includes(type)
        }
        return true
    };

    // 处理上传
    handleUpload = async(file, fileList) => {
        var fileID;
        try {
            fileID = file.uid + this.generateHash(file.name) + "."+ this.getFileExtension(file);
            console.log('文件ID:', fileID);
        } catch (error) {
            fileID =  file.name;
            console.error('生成文件ID时出错:', error);
        }
        console.log('文件:', file,fileList);
        // 文件类型校验
        console.log("文件类型:" + file.type);
        if (!this.checkFileType(file.type)){
            message.error("不支持的文件类型")
        }else {
            this.setState({
                data: {
                    "file" : file,
                    "len" : file.size,
                    "name" : fileID,
                    "type" : file.type,
                    "chunkNum" :  Math.ceil(file.size/this.state.chunkSize),
                },
                disabled:true,
                is_show_process:true,
                currentTrunk:0, //当前上传分片的索引
                percent:0,
            },function () {
                this.sendFile();
            });
        }

        return false
    };

    handleUploadChange = (v) => {
        if (v.fileList.length === 0) {
            this.setState({fileList: []})
        }
    };

    handlePreview = async file => {
        if (!file.thumbUrl){
            message.warning("该文件不支持预览")
        }else {
            if (!file.url && !file.preview) {
                file.preview = await this.getBase64(file.originFileObj);
            }
            this.setState({
                previewImage: file.url || file.preview,
                previewVisible: true,
            });
        }
    };

    getBase64 = (file) => {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => resolve(reader.result);
            reader.onerror = error => reject(error);
        });
    };

    handleCancel = () => this.setState({ previewVisible: false });

    handleRemove = (file) => {
        let list = [];
        this.state.fileList.map( item => {
            if (item !== file){
                list.push(item)
            }
            return true;
        });
        let that = this;
        this.setState({
            fileList:list
        },function () {
            let obj = {};
            obj[that.props.field ? that.props.field : "default_upload_file"] = JSON.stringify(that.state.fileList);
            this.props.form.setFieldsValue(obj);
        })
    };

    componentDidMount = () => {
        if (Array.isArray(this.props.initialValue)){
            let obj = {};
            obj[this.props.field ? this.props.field : "default_upload_file"] = JSON.stringify(this.props.initialValue);
            this.props.form.setFieldsValue(obj);
        }
    };

    render() {
        const {getFieldDecorator} = this.props.form;
        const {label,field,initialValue,rules,disabled} = this.props;
        const new_props = diffProps(this.props,["form","label","field","initialValue","rules"]);
        return (
            <Form.Item label={label ? label : "文件上传"} disabled={disabled} {...new_props}>
                {getFieldDecorator(field ? field : "default_upload_file", {initialValue: initialValue,rules: rules ? rules : []})(
                    <Fragment>
                        <Upload
                            listType={'picture'}
                            fileList={this.state.fileList}
                            beforeUpload={this.handleUpload}
                            onChange={this.handleUploadChange}
                            onPreview={this.handlePreview}
                            onRemove={this.handleRemove}
                        >
                            <Button  disabled={this.state.disabled}><Icon type="upload" />选择文件</Button>
                            <div style={{lineHeight: 2,fontSize:"12px",color:"red"}}>
                                {
                                    this.props.fileType ?
                                        '小提示:请上传"' + this.props.fileType.join('","') + '"类型的文件'
                                        :
                                        ""
                                }
                            </div>
                        </Upload>
                        <Progress style={{display:this.state.is_show_process ? "block" : "none"}} percent={parseInt(this.state.percent)} />
                        <Modal visible={this.state.previewVisible} footer={null} onCancel={this.handleCancel}>
                            <img alt="example" style={{ width: '100%' }} src={this.state.previewImage} />
                        </Modal>
                    </Fragment>
                )}
            </Form.Item>
        );
    }
}

export default FormUpload;
